#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "msg_pack.h"
#include "my_camera.h"

int fd;
int camera_capture_task_flag = 0;
char devid[] = "dev0407";
pthread_mutex_t mutex;

extern unsigned int pic_index;
extern unsigned int pic_num;
static int start = 0;

int recved = 1;

void *heart_task(void *args)
{
    while (1)
    {
        pthread_mutex_lock(&mutex);
        msg_pack_t *pack = pack_create(PACK_DEV_HEART);
        pack_add_field(pack, strlen(devid) + 1, devid);
        char *buf = (char *)malloc(sizeof(char) * pack->totalLen);
        pack_2_buf(pack, buf);
        send(fd, buf, pack->totalLen, 0);
        free(buf);
        free(pack);
        pthread_mutex_unlock(&mutex);
        sleep(10);
    }
}

void *pic_send_task(void *args)
{
    while (1)
    {
        for (; start < pic_index; start++)
        {
            // 发送
            char picture_name[20];
            sprintf(picture_name, "picture%d.yuv", start);
            printf("1111:[%d] picturename=[%s]\r\n", __LINE__,picture_name);
            FILE *fp = fopen(picture_name, "r");
            // 数据发送
            int total = 160 * 120 * 2 / 1200;
            for (int packno = 0; packno < total; packno++)
            {
                while (!recved)
                {
                }; // 等回复
                char buf[1200];
                msg_pack_t *pack = pack_create(PACK_DEV_VEDIO);
                pack_add_field(pack, strlen(devid) + 1, devid); // devid
                pack_add_field(pack, 4, (char *)&total);
                pack_add_field(pack, 4, (char *)&packno);
                fread(buf, 1, 1200, fp);
                pack_add_field(pack, 1200, buf);
                //
                char buf2[1200 + 50];
                pack_2_buf(pack, buf2);
                //
                recved = 0; // 还没有收到回复
                pthread_mutex_lock(&mutex);
                ssize_t cnt = send(fd, buf2, pack->totalLen, 0);
                printf("[%s],packno=[%d],cnt=[%ld]\r\n", picture_name, packno, cnt);
                pthread_mutex_unlock(&mutex);
                printf("2222:[%d] picturename=[%s]\r\n", __LINE__,picture_name);
                free(pack);
                printf("3333:[%d] picturename=[%s]\r\n", __LINE__,picture_name);
            }
            // 关闭文件
            fclose(fp);
            printf("4444:[%d] picturename=[%s]\r\n", __LINE__,picture_name);
            // 删除文件
            // remove(picture_name);
        }
    }
}

void *camera_capture_task(void *args)
{
    int fd = camera_device_open(DRV_NAME);
    init_camera_attribute(fd);
    start_capturing(fd);
    // 拍照计数清0
    pic_index = 0;
    pic_num = 0;
    start = 0;
    while (1)
    {
        if (camera_capture_task_flag == 0)
            break; // 退出了
        // 拍照并生成文件
        when_to_read(fd);
        // 先每一秒抓拍一张
        sleep(1);
    }
    stop_capturing(fd);
    uninit_camera(fd);
}

int main()
{
    // tcp客户端
    fd = socket(AF_INET, SOCK_STREAM, 0);
    //
    pthread_mutex_init(&mutex, NULL);
    //
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8888);
    addr.sin_addr.s_addr = inet_addr("192.168.1.210");

    if (0 != connect(fd, (struct sockaddr *)&addr, sizeof(addr)))
    {
        printf("连接服务器失败\n");
        return -1;
    }

    // 心跳发送线程
    pthread_t tid;
    pthread_create(&tid, NULL, heart_task, NULL);
    pthread_detach(tid);
    // 视频流数据发送线程
    pthread_create(&tid, NULL, pic_send_task, NULL);
    pthread_detach(tid);

    // 主线程接收数据
    while (1)
    {
        msg_pack_t *pack = pack_from_socket(fd);
        if (pack == NULL)
        {
            printf("远程服务器异常，本进程也即将停止\n");
            exit(EXIT_SUCCESS);
        }
        if (pack->type == PACK_START_CAMERA)
        {
            // 开启抓拍线程
            printf("recv cmd of START capture\n");
            if (camera_capture_task_flag == 0)
            {
                pthread_create(&tid, NULL, camera_capture_task, NULL);
                camera_capture_task_flag = 1;
            }
        }
        else if (pack->type == PACK_STOP_CAMERA)
        {
            printf("recv cmd of END capture\n");
            camera_capture_task_flag = 0; // 结束线程
            pthread_join(tid, NULL);      // 回收线程资源，并阻塞式等待摄像头关闭
        }
        else if (pack->type == PACK_DEV_VEDIO_RET)
        {
            recved = 1;
        }
        pack_destroy(pack);
    }

    return 0;
}